package com.ray.test.proxy;

import com.alibaba.fastjson.JSON;
import com.ray.test.serializable.ProtostuffSerializable;
import com.ray.test.serializable.Serializable;
import com.ray.test.util.MethodRunUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: cjlib代理
 * @Class: MethodHander
 * @Package com.ray.test.proxy
 * @date 2019/12/18 10:25
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Slf4j
public class ParamsHander implements MethodInterceptor, InvocationHandler {

    /***spring容器**/
    private ApplicationContext applicationContext;
    private Object target;

    public ParamsHander(ApplicationContext applicationContext, Object target) {
        this.applicationContext = applicationContext;
        this.target = target;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        return doAll(o, method, objects);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return doAll(proxy, method, args);
    }

    private Object doAll(Object proxy, Method method, Object[] args) throws Throwable {
        MockTestConfig config = MockTestConfig.get();
        if (config != null && config.isMock()) {
            if (!config.isHasData()) {
                //设置是否刷新数据
                config.setReflush(true);
                //设置请求参数
                List<MethodRequest> methodRequests = new ArrayList<>();
                int index = 0;
                try{
                    for (Object p : args) {
                        if(p == null){
                            methodRequests.add(new MethodRequest(index++, null, null));
                        }else {
                            methodRequests.add(new MethodRequest(index++, p.getClass(), p));
                        }
                    }
                }catch (Exception e){
                 log.info("参数构建异常",e);
                 throw new RuntimeException("参数构建异常");
                }
                log.info("方法：{}，参数数量:{}",method.getName(),methodRequests.size());
                //本行代码 莫名其妙不被执行 抓狂
                config.getMockData().setRequests(methodRequests);
            } else {
                List<MethodRequest> methodRequests = config.getMockData().getRequests();
                List<Object> params = methodRequests.stream().sorted(Comparator.comparing(MethodRequest::getIndex))
                        .map(MethodRequest::getData).collect(Collectors.toList());
                args = params.toArray();
            }
        }
        //请求结果
        log.info("{}请求参数：{}",method.getName(), JSON.toJSONString(args));
        Object result = MethodRunUtil.invoke(method,target, args);
        config = MockTestConfig.get();
        if (config != null && config.isReflush()) {
            log.info("方法{},写入文件:{}", config.getName(), JSON.toJSONString(config.getMockData()));
            Serializable serializable = (Serializable)config.getMockDataType().newInstance();
            serializable.set(config);
        }
        return result;
    }
}
